package com.kaifamiao;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Logger;

public class ProxyTest {

    public static void main(String[] args) {

        // 代理目标: 谁被别人代理谁就是代理目标 (相当于工厂)
        final Object target = new Dog() ;

        // 获取代理目标的类型
        final Class<?> c = target.getClass();
        // 获得用于加载 c 类的 "类加载器"
        final ClassLoader loader = c.getClassLoader();
        // 获得 c 类 直接实现的接口们
        final Class<?>[] interfaces = c.getInterfaces();

        // 创建一个 "调用处理者" (此处使用匿名内部类方式实现)
        final InvocationHandler handler = new InvocationHandler() {
            // 为匿名内部类定义的实例字段
            Logger logger = Logger.getLogger(this.getClass().getName());
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                logger.info( "方法[" + method.getName() + "]即将执行" );
                // 通过反射调用 target 的 method 方法
                Object res = method.invoke( target, args ); // target.method( args )
                return res;
            }
        };

        // 代理对象: 谁取代理别人谁就是代理对象 (相当于代理商)
        Object proxy = Proxy.newProxyInstance( loader, interfaces, handler );
        System.out.println( proxy.toString() );

        // 判断 proxy 是否时 Addable 类型
        if( proxy instanceof  Addable ) {
            Addable a = (Addable) proxy;
            // 调用 代理对象的 add 方法 会被 handler 指派给 代理目标
            int res = a.add( 10, 20 );
            System.out.println( res );
        }

        InvocationHandler h = Proxy.getInvocationHandler( proxy );
        System.out.println( handler == h ); // true
    }

}
